package com.cryptoneedle.center.source.service.feature;


import com.baomidou.dynamic.datasource.annotation.DS;
import com.cryptoneedle.center.source.entity.metadata.SourceCatalog;
import com.cryptoneedle.center.source.entity.metadata.SourceDatabase;
import com.cryptoneedle.center.source.properties.DorisProperties;
import com.cryptoneedle.center.source.properties.SshProperties;
import com.cryptoneedle.center.source.service.constraint.*;
import com.cryptoneedle.center.source.service.enhance.SourceEnhanceDimensionService;
import com.cryptoneedle.center.source.service.enhance.SourceEnhanceDorisAnalyzeColumnService;
import com.cryptoneedle.center.source.service.enhance.SourceEnhanceDorisAnalyzeTableService;
import com.cryptoneedle.center.source.service.enhance.SourceEnhanceIncrementService;
import com.cryptoneedle.center.source.service.metadata.*;
import com.cryptoneedle.center.source.util.SshManager;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>description: 源数据源-同步服务 </p>
 *
 * @author CryptoNeedle
 * @date 2025-06-23
 */
@DS("pg")
@Slf4j
@Service
public class SourceSyncService {
    
    @Resource
    private SourceTestService sourceTestService;
    
    @Resource
    private SourceSyncService sourceSyncService;
    
    @Resource
    private SourceJdbcService sourceJdbcService;
    
    @Resource
    private SourceServerService sourceServerService;
    
    @Resource
    private SourceCatalogService sourceCatalogService;
    
    @Resource
    private SourceDatabaseService sourceDatabaseService;
    
    @Resource
    private SourceTableService sourceTableService;
    
    @Resource
    private SourceColumnService sourceColumnService;
    
    @Resource
    private SourceConstraintPrimaryService sourceConstraintPrimaryService;
    
    @Resource
    private SourceConstraintUniqueService sourceConstraintUniqueService;
    
    @Resource
    private SourceConstraintForeignService sourceConstraintForeignService;
    
    @Resource
    private SourceConstraintCheckService sourceConstraintCheckService;
    
    @Resource
    private SourceIndexUniqueService sourceIndexUniqueService;
    
    @Resource
    private SourceEnhanceDorisAnalyzeTableService sourceEnhanceDorisAnalyzeTableService;
    
    @Resource
    private SourceEnhanceDorisAnalyzeColumnService sourceEnhanceDorisAnalyzeColumnService;
    
    @Resource
    private SourceEnhanceIncrementService sourceEnhanceIncrementService;
    
    @Resource
    private SourceEnhanceDimensionService sourceEnhanceDimensionService;
    
    @Resource
    private SshProperties sshProperties;
    
    @Resource
    private DorisProperties dorisProperties;
    
    @Resource
    private SshManager sshManager;
    
    @Resource
    private JdbcTemplate jdbcTemplate;
    
    @Transactional
    public void syncAll() {
        List<SourceCatalog> sourceCatalogs = sourceCatalogService.findAll();
        for (SourceCatalog sourceCatalog : sourceCatalogs) {
            try {
                sourceSyncService.syncSourceCatalog(sourceCatalog);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    public void syncSourceCatalog(String sourceCatalogName) {
        SourceCatalog sourceCatalog = sourceCatalogService.getById(sourceCatalogName);
        if (sourceCatalog == null) {
            throw new RuntimeException("[SYNC] Source catalog not found: " + sourceCatalogName);
        }
        sourceSyncService.syncSourceCatalog(sourceCatalog);
    }
    
    public void syncSourceCatalog(SourceCatalog sourceCatalog) {
        String sourceCatalogName = sourceCatalog.getSourceCatalogName();
        
        // 测试
        sourceTestService.testCatalogConnection(sourceCatalog);
        if (!sourceCatalog.getSourceJdbc().getSourceServer().getConnected()) {
            throw new RuntimeException("[SYNC] Server Not Connected");
        }
        if (!sourceCatalog.getSourceJdbc().getConnected()) {
            throw new RuntimeException("[SYNC] JDBC Not Connected");
        }
        
        List<SourceDatabase> sourceDatabases = sourceDatabaseService.listEnabled(sourceCatalog);
        if (sourceDatabases.isEmpty()) {
            throw new RuntimeException("[SYNC] Database Not Enabled");
        }
        
        log.info("[SYNC] {} =======================> [开始]", sourceCatalogName);
        for (SourceDatabase sourceDatabase : sourceDatabases) {
            sourceSyncService.syncSourceDatabase(sourceCatalog, sourceDatabase);
        }
        log.info("[SYNC] {} =======================> [开始]", sourceCatalogName);
    }
    
    public void syncSourceDatabase(SourceCatalog sourceCatalog, SourceDatabase sourceDatabase) {
        sourceDatabaseService.syncSource(sourceCatalog, sourceDatabase);
        sourceTableService.syncSource(sourceCatalog, sourceDatabase);
        sourceColumnService.syncSource(sourceCatalog, sourceDatabase);
        sourceConstraintPrimaryService.syncSource(sourceCatalog, sourceDatabase);
        sourceConstraintUniqueService.syncSource(sourceCatalog, sourceDatabase);
        sourceConstraintForeignService.syncSource(sourceCatalog, sourceDatabase);
        sourceConstraintCheckService.syncSource(sourceCatalog, sourceDatabase);
        sourceIndexUniqueService.syncSource(sourceCatalog, sourceDatabase);
        
        //dorisAnalyzeService.dorisStatistic(sourceCatalog, sourceDatabase);
    }
}